﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
using System.Threading;

namespace AvgCutImage
{
    public partial class FmMain : Form
    {
        string SavePath = Path.Combine(Environment.CurrentDirectory, "AvgCutImage");
        public FmMain()
        {
            InitializeComponent();
            SavePath = Path.Combine(SavePath,DateTime.Now.ToString("yyyyMMdd"));
            if (!Directory.Exists(SavePath))
            {
                Directory.CreateDirectory(SavePath);
            }
        }
        //定义委托
        private delegate void UpdateUiDelegate();

        ImageFormat imgFormat;
        //控件值
        string imgSuffix = "png";
        int numCutCellsValue;
        int numCutRowsValue;
        int numPixelValue;
        bool isPixel = false;
        //当前行
        DataGridViewRow CurrentRow;

        //选择图片
        private void btSelectImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog opfd = new OpenFileDialog();
            opfd.Filter = "图片文件(*.jpg,*.jpeg,*.bmp,*.png)|*.jpg;*.jpeg;*.bmp;*.png";
            opfd.InitialDirectory = Environment.CurrentDirectory;
            opfd.Multiselect = true;
            opfd.Title = "请选择要切割的图片";
            if (opfd.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) return;
            string[] paths = opfd.FileNames;
            foreach (string path in paths)
            {
                this.AddItemImg(path);
            }
        }

        /// <summary>
        /// 设置控件启用、禁用
        /// </summary>
        /// <param name="disable"></param>
        private void Disable(bool disable)
        {
            btCut.Enabled = disable;
            cboType.Enabled = disable;
            numCutCells.Enabled = disable;
            numCutRows.Enabled = disable;
            numPixel.Enabled = disable;
            像素.Enabled = disable;
            均分.Enabled = disable;
            btnRemoveImg.Enabled = disable;
            btSelectImage.Enabled = disable;
        }

        //开始图片切割
        private void btCut_Click(object sender, EventArgs e)
        {
            //初始化值
            imgSuffix = cboType.SelectedItem.ToString();
            numCutCellsValue = (int)numCutCells.Value;
            numCutRowsValue = (int)numCutRows.Value;
            numPixelValue = (int)numPixel.Value;
            isPixel = 像素.Checked;
            this.Disable(false);
            //开启线程
            Thread th = new Thread(()=> 
            {
                foreach (DataGridViewRow r in dgvData.Rows)
                {
                    CurrentRow = r;
                    this.Invoke(new UpdateUiDelegate(delegate{
                        CurrentRow.Cells["status"].Value = "处理中···";
                        dgvData.CurrentCell = CurrentRow.Cells[0];
                    }));
                    string path = CurrentRow.Cells["path"].FormattedValue.ToString();
                    //切图
                    Cut(path);
                }
                //打开文件夹
                this.Invoke(new UpdateUiDelegate(delegate {
                    System.Diagnostics.Process.Start("explorer.exe", SavePath);
                    this.Disable(true);
                }));
            });
            th.IsBackground = true;
            th.Start();            
        }

        /// <summary>
        /// 切割图片
        /// </summary>
        /// <param name="path">图片路径</param>
        private void Cut(string path)
        {
            //获取图片信息
            FileInfo fileImg = new FileInfo(path);
            string fileImgName = fileImg.Name.Remove(fileImg.Name.LastIndexOf("."));
            string imgPath = Path.Combine(SavePath, fileImgName);
            if (!Directory.Exists(imgPath))
            {
                Directory.CreateDirectory(imgPath);
            }
            imgFormat = getImageFormat();
            using (Bitmap b = new Bitmap(fileImg.FullName))
            {
                int avgWidth = b.Width / numCutCellsValue;//每块的平均宽度
                int avgHeight = b.Height / numCutRowsValue;//每块的平均高度
                if (isPixel)
                {
                    avgWidth = b.Width;//每块的平均宽度                    
                    avgHeight = numPixelValue;
                    if (avgHeight > b.Height)
                    {
                        avgHeight = b.Height;
                    }
                }
                int bW = b.Width;
                int bH = b.Height;
                List<Rectangle> lstRect = CreateAvgCutRectangle(bW, bH, avgWidth, avgHeight);
                for (int i = 0; i < lstRect.Count; i++)
                {
                    CutImage(b, lstRect[i].X, lstRect[i].Y, lstRect[i].Width, lstRect[i].Height,
                        string.Format("{0}\\{1}.{2}", fileImgName, NumToNostring(i), imgSuffix));
                    this.Invoke(new UpdateUiDelegate(delegate
                    {
                        if (CurrentRow != null && CurrentRow.Index > -1)
                        {
                            CurrentRow.Cells["status"].Value = string.Format("正在切割第{0}张···", (i + 1));
                        }
                    }));
                }
                this.Invoke(new UpdateUiDelegate(delegate
                {
                    if (CurrentRow != null && CurrentRow.Index > -1)
                    {
                        CurrentRow.Cells["status"].Value = "处理完成";
                    }
                }));                
            }            
        }


        /// <summary>
        /// 把原始图片按照指定的分块切割并保存到目标路径中
        /// </summary>
        /// <param name="img">原始图片即要切割的图片</param>
        /// <param name="srcX">切割左上角点X坐标</param>
        /// <param name="srcY">切割左上角点Y坐标</param>
        /// <param name="srcWidth">切割宽度</param>
        /// <param name="srcHeight">切割高度</param>
        /// <param name="dstImagePath">要保存到的目标路径</param>
        private void CutImage(Image img, int srcX, int srcY, int srcWidth, int srcHeight, string dstImagePath)
        {
            int dstWidth = srcWidth, dstHeight = srcHeight;
            using (Bitmap bitmap = new Bitmap(dstWidth, dstHeight))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.DrawImage(img, new Rectangle(0, 0, dstWidth, dstHeight),
                            new Rectangle(srcX, srcY, srcWidth, srcHeight), GraphicsUnit.Pixel);
                    g.Save();
                    string savePath = Path.Combine(SavePath, dstImagePath);
                    bitmap.Save(savePath, imgFormat);
                }
            }
        }

        /// <summary>
        /// 获取图片保存类型
        /// </summary>
        /// <returns></returns>
        private ImageFormat getImageFormat()
        {
            ImageFormat iformat = null;
            switch (imgSuffix)
            {
                case "png":
                    iformat = ImageFormat.Png;
                    break;
                case "jpg":
                    iformat = ImageFormat.Jpeg;
                    break;
                default:
                    iformat = ImageFormat.Bmp;
                    break;
            }
            return iformat;
        }


        /// <summary>
        /// 根据原始图像大小和要切割的数量创建切割分块合集
        /// </summary>
        /// <param name="imgWidth">要切割的图片的宽度</param>
        /// <param name="imgHeight">要切割的图片的高度</param>
        /// <param name="avgWidth">要切割的像素宽度</param>
        /// <param name="avgHeight">要切割的像素高度</param>
        /// <returns></returns>
        private List<Rectangle> CreateAvgCutRectangle(int imgWidth, int imgHeight, int avgWidth, int avgHeight)
        {
            List<Rectangle> lstRect = new List<Rectangle>();
            //int avgWidth = imgWidth / cutCellsNum;//每块的平均宽度
            //int avgHeight = imgHeight / cutRowsNum;//每块的平均高度
            int offsetX = 0, offsetY = 0;
            int cutHeight = avgHeight;
            int cutWidth = avgWidth;
            while (true)
            {
                //列分块
                if (imgHeight - offsetY < avgHeight * 2)
                {
                    cutHeight = imgHeight - offsetY;
                }

                offsetX = 0;
                cutWidth = avgWidth;
                while (true)
                {
                    //行分块
                    if (imgWidth - offsetX < avgWidth * 2)
                    {
                        cutWidth = imgWidth - offsetX;
                    }
                    lstRect.Add(new Rectangle(offsetX, offsetY, cutWidth, cutHeight));
                    offsetX += cutWidth;
                    if (offsetX >= imgWidth) break;
                }
                offsetY += cutHeight;
                if (offsetY >= imgHeight) break;
            }
            return lstRect;
        }

        /// <summary>
        /// 把数值转换成等长字符串，前加0
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private string NumToNostring(int num)
        {
            string zero = string.Empty;
            if (num < 10) zero = "00";
            else if (num < 100) zero = "0";
            else zero = "";
            return zero + num.ToString();
        }

        //正在拖拽中
        private void FmMain_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        //拖拽完成时
        private void FmMain_DragDrop(object sender, DragEventArgs e)
        {
            //检测是否是windows格式
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                //获取拖放的文件列表
                string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
                foreach (string it in paths)
                {
                    FileInfo f = new FileInfo(it);
                    //拖放的第一个文件的不能是目录并且扩展名必须是.PP 
                    if (f.Attributes != FileAttributes.Directory && "*.jpg;*.jpeg;*.bmp;*.png".Contains(f.Extension))
                    {
                        string path = it;
                        this.AddItemImg(path);
                    }
                    //else { MessageBox.Show("不是图片文件或不支持的图片格式！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); }
                }                
            }
        }

        private void FmMain_Load(object sender, EventArgs e)
        {
            cboType.SelectedItem = imgSuffix;
        }
        

        /// <summary>
        /// 添加图片到任务列表
        /// </summary>
        /// <param name="path"></param>
        private void AddItemImg(string path)
        {
            if (!isExist(path))
            {
                int index = dgvData.Rows.Add();
                DataGridViewRow row = dgvData.Rows[index];
                row.Cells["path"].Value = path;
                row.Cells["status"].Value = "";
            }
        }

        /// <summary>
        /// 判断是否存在图片
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <returns></returns>
        private bool isExist(string path)
        {
            bool isExist = false;
            if (!string.IsNullOrEmpty(path))
            {
                string itemPath = "";
                foreach (DataGridViewRow row in dgvData.Rows)
                {
                    itemPath = row.Cells["path"].FormattedValue.ToString();
                    if (path.Equals(itemPath))
                    {
                        isExist = true;
                        break;
                    }
                }
            }
            return isExist;
        }

        /// <summary>
        /// 移除图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRemoveImg_Click(object sender, EventArgs e)
        {
            if (dgvData.Rows.Count > 0)
            {
                if (MessageBox.Show("您确定移除当前选中的图片吗？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
                {
                    foreach (DataGridViewRow row in dgvData.SelectedRows)
                    {
                        dgvData.Rows.Remove(row);
                    }                    
                }
            }
        }

        /// <summary>
        /// 点击行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvData_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > 0)
            {
                
            }            
        }
    }
}
